//package com.smrtcold.dev.plc;
//
//import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
//import org.eclipse.milo.opcua.sdk.client.api.subscriptions.ManagedSubscription;
//import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem;
//import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedSubscription;
//import org.eclipse.milo.opcua.stack.core.AttributeId;
//import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
//import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
//import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
//import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
//import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
//import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
//import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest;
//import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters;
//import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
//
//import javax.swing.*;
//import javax.swing.table.DefaultTableModel;
//import java.awt.*;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.UUID;
//import java.util.concurrent.CompletableFuture;
//import java.util.concurrent.atomic.AtomicLong;
//
//public class PLCDataMonitor extends JFrame {
//
//    private final JTextField serverUrlField = new JTextField("opc.tcp://localhost:4840", 30);
//    private final JButton connectButton = new JButton("连接");
//    private final JButton disconnectButton = new JButton("断开");
//    private final JButton addMonitorButton = new JButton("添加监控点");
//    private final JTable dataTable = new JTable();
//    private final JTextArea logArea = new JTextArea(8, 60);
//    private final JLabel statusLabel = new JLabel("未连接");
//
//    private OpcUaClient client;
//    private ManagedSubscription subscription;
//    private final List<MonitoredPoint> monitoredPoints = new ArrayList<>();
//    private final DefaultTableModel tableModel = new DefaultTableModel(
//            new Object[]{"节点ID", "当前值", "最后更新时间", "变化次数"}, 0
//    );
//
//    // 用于生成唯一的客户端句柄
//    private final AtomicLong clientHandleCounter = new AtomicLong(1);
//
//    public PLCDataMonitor() {
//        super("PLC数据监控系统 - OPC UA订阅");
//        initializeUI();
//        setupEventListeners();
//    }
//
//    private void initializeUI() {
//        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        setSize(900, 600);
//        setLayout(new BorderLayout(10, 10));
//
//        // 顶部控制面板
//        JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
//        controlPanel.add(new JLabel("OPC UA服务器:"));
//        controlPanel.add(serverUrlField);
//        controlPanel.add(connectButton);
//        controlPanel.add(disconnectButton);
//        controlPanel.add(addMonitorButton);
//        disconnectButton.setEnabled(false);
//        add(controlPanel, BorderLayout.NORTH);
//
//        // 中央数据表格
//        dataTable.setModel(tableModel);
//        dataTable.setRowHeight(25);
//        JScrollPane tableScroll = new JScrollPane(dataTable);
//        tableScroll.setBorder(BorderFactory.createTitledBorder("监控数据点"));
//        add(tableScroll, BorderLayout.CENTER);
//
//        // 底部日志区域
//        logArea.setEditable(false);
//        JScrollPane logScroll = new JScrollPane(logArea);
//        logScroll.setBorder(BorderFactory.createTitledBorder("系统日志"));
//        add(logScroll, BorderLayout.SOUTH);
//
//        // 状态栏
//        JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
//        statusPanel.add(statusLabel);
//        add(statusPanel, BorderLayout.SOUTH);
//
//        // 初始添加一些示例监控点
//        addSampleMonitoredPoints();
//
//        setLocationRelativeTo(null);
//    }
//
//    private void addSampleMonitoredPoints() {
//        monitoredPoints.add(new MonitoredPoint("温度传感器", "ns=2;s=Temperature"));
//        monitoredPoints.add(new MonitoredPoint("压力传感器", "ns=2;s=Pressure"));
//        monitoredPoints.add(new MonitoredPoint("电机状态", "ns=2;s=Motor.Status"));
//        monitoredPoints.add(new MonitoredPoint("生产线速度", "ns=2;s=ProductionLine.Speed"));
//        monitoredPoints.add(new MonitoredPoint("能耗", "ns=2;s=EnergyConsumption"));
//
//        for (MonitoredPoint point : monitoredPoints) {
//            tableModel.addRow(new Object[]{
//                    point.getDisplayName(),
//                    "N/A",
//                    "未连接",
//                    0
//            });
//        }
//    }
//
//    private void setupEventListeners() {
//        connectButton.addActionListener(e -> connectToServer());
//        disconnectButton.addActionListener(e -> disconnectFromServer());
//        addMonitorButton.addActionListener(e -> addNewMonitorPoint());
//    }
//
//    private void connectToServer() {
//        String serverUrl = serverUrlField.getText().trim();
//        if (serverUrl.isEmpty()) {
//            log("错误: 服务器地址不能为空");
//            return;
//        }
//
//        log("正在连接到: " + serverUrl);
//        statusLabel.setText("连接中...");
//
//        // 使用SwingWorker在后台线程中执行连接操作
//        new SwingWorker<Void, String>() {
//            @Override
//            protected Void doInBackground() throws Exception {
//                try {
//                    // 创建OPC UA客户端
//                    client = OpcUaClient.create(serverUrl);
//                    client.connect().get(); // 等待连接完成
//
//                    // 创建托管订阅
//                    subscription = ManagedSubscription.create(client, 500.0);
//                    log("创建托管订阅成功");
//
//                    // 为所有监控点创建监控项
//                    for (int i = 0; i < monitoredPoints.size(); i++) {
//                        MonitoredPoint point = monitoredPoints.get(i);
//                        createMonitoredItem(point, i);
//                    }
//
//                    publish("连接成功!");
//                } catch (Exception ex) {
//                    publish("连接失败: " + ex.getMessage());
//                    ex.printStackTrace();
//                }
//                return null;
//            }
//
//            @Override
//            protected void process(List<String> chunks) {
//                for (String message : chunks) {
//                    log(message);
//                    if (message.startsWith("连接成功")) {
//                        statusLabel.setText("已连接");
//                        connectButton.setEnabled(false);
//                        disconnectButton.setEnabled(true);
//                    } else if (message.startsWith("连接失败")) {
//                        statusLabel.setText("连接失败");
//                    }
//                }
//            }
//        }.execute();
//    }
//
//    private void createMonitoredItem(MonitoredPoint point, int rowIndex) {
//        try {
//            NodeId nodeId = NodeId.parse(point.getNodeId());
//
//            // 创建ReadValueId
//            ReadValueId readValueId = new ReadValueId(
//                    nodeId,
//                    AttributeId.Value.uid(), // 监控值属性
//                    null,
//                    QualifiedName.NULL_VALUE
//            );
//
//            // 创建唯一的客户端句柄
//            UInteger clientHandle = UInteger.valueOf(clientHandleCounter.getAndIncrement());
//
//            // 监控参数配置
//            MonitoringParameters parameters = new MonitoringParameters(
//                    clientHandle,
//                    100.0, // 采样间隔(ms)
//                    null,   // 过滤器
//                    UInteger.valueOf(1), // 队列大小
//                    true    // 丢弃旧值
//            );
//
//            // 创建监控项请求
//            MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(
//                    readValueId,
//                    MonitoringMode.Reporting,
//                    parameters
//            );
//
//            // 创建监控项并设置回调
//            CompletableFuture<UaMonitoredItem> future = subscription.createMonitoredItem(
//                    request,
//                    TimestampsToReturn.Both,
//                    (item, value) -> handleDataChange(item, value, rowIndex)
//            );
//
//            // 等待监控项创建完成
//            UaMonitoredItem monitoredItem = future.get();
//            point.setMonitoredItem(monitoredItem);
//
//            log("已监控: " + point.getDisplayName() + " [" + point.getNodeId() + "]");
//        } catch (Exception ex) {
//            log("创建监控项失败: " + point.getNodeId() + " - " + ex.getMessage());
//            ex.printStackTrace();
//        }
//    }
//
//    private void handleDataChange(UaMonitoredItem item, DataValue value, int rowIndex) {
//        if (value != null && value.getValue() != null) {
//            MonitoredPoint point = monitoredPoints.get(rowIndex);
//            Object newValue = value.getValue().getValue();
//
//            // 更新监控点数据
//            point.setCurrentValue(newValue);
//            point.incrementChangeCount();
//
//            // 更新UI
//            SwingUtilities.invokeLater(() -> {
//                tableModel.setValueAt(newValue, rowIndex, 1);
//                tableModel.setValueAt(java.time.LocalTime.now().toString(), rowIndex, 2);
//                tableModel.setValueAt(point.getChangeCount(), rowIndex, 3);
//
//                // 记录变化日志
//                log("数据变化: " + point.getDisplayName() + " = " + newValue);
//            });
//        }
//    }
//
//    private void disconnectFromServer() {
//        new SwingWorker<Void, String>() {
//            @Override
//            protected Void doInBackground() throws Exception {
//                try {
//                    if (subscription != null) {
//                        subscription.delete();
//                        publish("订阅已删除");
//                    }
//
//                    if (client != null) {
//                        client.disconnect().get();
//                        publish("已断开连接");
//                    }
//                } catch (Exception ex) {
//                    publish("断开连接时出错: " + ex.getMessage());
//                }
//                return null;
//            }
//
//            @Override
//            protected void process(List<String> chunks) {
//                for (String message : chunks) {
//                    log(message);
//                    if (message.startsWith("已断开连接")) {
//                        statusLabel.setText("已断开");
//                        connectButton.setEnabled(true);
//                        disconnectButton.setEnabled(false);
//                    }
//                }
//            }
//        }.execute();
//    }
//
//    private void addNewMonitorPoint() {
//        JTextField nameField = new JTextField();
//        JTextField nodeIdField = new JTextField();
//
//        Object[] fields = {
//                "显示名称:", nameField,
//                "节点ID (ns=...):", nodeIdField
//        };
//
//        int result = JOptionPane.showConfirmDialog(
//                this,
//                fields,
//                "添加监控点",
//                JOptionPane.OK_CANCEL_OPTION
//        );
//
//        if (result == JOptionPane.OK_OPTION) {
//            String name = nameField.getText().trim();
//            String nodeId = nodeIdField.getText().trim();
//
//            if (!name.isEmpty() && !nodeId.isEmpty()) {
//                MonitoredPoint point = new MonitoredPoint(name, nodeId);
//                monitoredPoints.add(point);
//                tableModel.addRow(new Object[]{name, "N/A", "未连接", 0});
//
//                // 如果已连接，立即开始监控
//                if (client != null && subscription != null) {
//                    int rowIndex = monitoredPoints.size() - 1;
//                    createMonitoredItem(point, rowIndex);
//                }
//            }
//        }
//    }
//
//    private void log(String message) {
//        SwingUtilities.invokeLater(() -> {
//            logArea.append("[" + java.time.LocalTime.now() + "] " + message + "\n");
//            logArea.setCaretPosition(logArea.getDocument().getLength());
//        });
//    }
//
//    public static void main(String[] args) {
//        SwingUtilities.invokeLater(() -> {
//            PLCDataMonitor monitor = new PLCDataMonitor();
//            monitor.setVisible(true);
//        });
//    }
//
//    // 监控点内部类
//    static class MonitoredPoint {
//        private final String displayName;
//        private final String nodeId;
//        private Object currentValue;
//        private int changeCount;
//        private UaMonitoredItem monitoredItem;
//
//        public MonitoredPoint(String displayName, String nodeId) {
//            this.displayName = displayName;
//            this.nodeId = nodeId;
//            this.currentValue = null;
//            this.changeCount = 0;
//        }
//
//        public String getDisplayName() {
//            return displayName;
//        }
//
//        public String getNodeId() {
//            return nodeId;
//        }
//
//        public Object getCurrentValue() {
//            return currentValue;
//        }
//
//        public void setCurrentValue(Object currentValue) {
//            this.currentValue = currentValue;
//        }
//
//        public int getChangeCount() {
//            return changeCount;
//        }
//
//        public void incrementChangeCount() {
//            this.changeCount++;
//        }
//
//        public UaMonitoredItem getMonitoredItem() {
//            return monitoredItem;
//        }
//
//        public void setMonitoredItem(UaMonitoredItem monitoredItem) {
//            this.monitoredItem = monitoredItem;
//        }
//    }
//}
